home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 201-225 / disk_217 / stevie / fileio.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  6KB  |  256 lines

  1. /*
  2.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  3.  *
  4.  * Code Contributions By : Tim Thompson           twitch!tjt
  5.  *                         Tony Andrews           onecom!wldrdg!tony 
  6.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  7.  */
  8.  
  9. #include "stevie.h"
  10.  
  11. void
  12. filemess(s)
  13.     char           *s;
  14. {
  15.     sprintf(IObuff, "\"%s\" %s", ((Filename == NULL) ? "" : Filename), s);
  16.     msg(IObuff);
  17. }
  18.  
  19. void
  20. renum()
  21. {
  22.     LPtr           *p;
  23.     unsigned long   l = 0;
  24.  
  25.     for (p = Filemem; p != NULL; p = nextline(p), l += LINEINC)
  26.     p->linep->num = l;
  27.  
  28.     Fileend->linep->num = 0xffffffffL;
  29. }
  30.  
  31. #ifdef  MEGAMAX
  32. overlay "fileio"
  33. #endif
  34.  
  35. bool_t
  36. readfile(fname, fromp, nochangename)
  37.     char           *fname;
  38.     LPtr           *fromp;
  39.     bool_t          nochangename;    /* if TRUE, don't change the Filename */
  40. {
  41.     FILE           *f, *fopen();
  42.     LINE           *curr;
  43.     char            buf2[80];
  44.     int             c;
  45.     int             IObuffsize = 0;
  46.     long            nchars = 0;
  47.     int             linecnt = 0;
  48.     bool_t          wasempty = bufempty();
  49.     int             nonascii = 0;    /* count garbage characters */
  50.     int             nulls = 0;    /* count nulls */
  51.     bool_t          incomplete = FALSE;    /* was the last line incomplete? */
  52.     bool_t          toolong = FALSE;    /* a line was too long */
  53.  
  54.     curr = fromp->linep;
  55.  
  56.     if (!nochangename)
  57.     Filename = strsave(fname);
  58.  
  59.     f = fopen(fname, "r");
  60.     if (f == NULL)
  61.     return TRUE;
  62.  
  63.     S_NOT_VALID;
  64.  
  65.     filemess("");
  66.  
  67.     do {
  68.     c = getc(f);
  69.  
  70.     if (c == EOF) {
  71.         if (IObuffsize == 0)/* normal loop termination */
  72.         break;
  73.  
  74.         /*
  75.          * If we get EOF in the middle of a line, note the fact and
  76.          * complete the line ourselves. 
  77.          */
  78.         incomplete = TRUE;
  79.         c = NL;
  80.     }
  81.     if (c >= 0x80) {
  82.         c -= 0x80;
  83.         nonascii++;
  84.     }
  85.     /*
  86.      * If we reached the end of the line, OR we ran out of space for it,
  87.      * then process the complete line. 
  88.      */
  89.     if (c == NL || IObuffsize == (IOSIZE - 1)) {
  90.         LINE           *lp;
  91.  
  92.         if (c != NL)
  93.         toolong = TRUE;
  94.  
  95.         IObuff[IObuffsize++] = NUL;
  96.         lp = newline(IObuffsize);
  97.         if (lp == NULL) {
  98.         fprintf(stderr, "not enough memory - should never happen");
  99.         getout(1);
  100.         }
  101.         strcpy(lp->s, IObuff);
  102.  
  103.         curr->next->prev = lp;    /* new line to next one */
  104.         lp->next = curr->next;
  105.  
  106.         curr->next = lp;    /* new line to prior one */
  107.         lp->prev = curr;
  108.  
  109.         curr = lp;        /* new line becomes current */
  110.         IObuffsize = 0;
  111.         linecnt++;
  112.     } else if (c == NUL) {
  113.         nulls++;        /* count and ignore nulls */
  114.     } else {
  115.         IObuff[IObuffsize++] = (char) c;    /* normal character */
  116.     }
  117.  
  118.     nchars++;
  119.     } while (!incomplete && !toolong);
  120.  
  121.     fclose(f);
  122.  
  123.     /*
  124.      * If the buffer was empty when we started, we have to go back and remove
  125.      * the "dummy" line at Filemem and patch up the ptrs. 
  126.      */
  127.     if (wasempty && linecnt != 0) {
  128.     LINE           *dummy = Filemem->linep;    /* dummy line ptr */
  129.  
  130.     Filemem->linep = Filemem->linep->next;
  131.     Filemem->linep->prev = Filetop->linep;
  132.     Filetop->linep->next = Filemem->linep;
  133.  
  134.     Curschar->linep = Filemem->linep;
  135.     Topchar->linep = Filemem->linep;
  136.  
  137.     free(dummy->s);        /* free string space */
  138.     free((char *) dummy);    /* free LINE struct */
  139.     }
  140.     renum();
  141.  
  142.     if (toolong) {
  143.     sprintf(IObuff, "\"%s\" Line too long", fname);
  144.     msg(IObuff);
  145.     return FALSE;
  146.     }
  147.     sprintf(IObuff, "\"%s\" %s%d line%s, %ld character%s",
  148.         fname,
  149.         incomplete ? "[Incomplete last line] " : "",
  150.         linecnt, (linecnt > 1) ? "s" : "",
  151.         nchars, (nchars > 1) ? "s" : "");
  152.  
  153.     buf2[0] = NUL;
  154.  
  155.     if (nonascii || nulls) {
  156.     if (nonascii) {
  157.         if (nulls)
  158.         sprintf(buf2, " (%d null, %d non-ASCII)",
  159.             nulls, nonascii);
  160.         else
  161.         sprintf(buf2, " (%d non-ASCII)", nonascii);
  162.     } else
  163.         sprintf(buf2, " (%d null)", nulls);
  164.     }
  165.     strcat(IObuff, buf2);
  166.     msg(IObuff);
  167.  
  168.     return FALSE;
  169. }
  170.  
  171. /*
  172.  * writeit - write to file 'fname' lines 'start' through 'end' 
  173.  *
  174.  * If either 'start' or 'end' contain null line pointers, the default is to use
  175.  * the start or end of the file respectively. 
  176.  */
  177. bool_t
  178. writeit(fname, start, end)
  179.     char           *fname;
  180.     LPtr           *start, *end;
  181. {
  182.     FILE           *f;
  183.     FILE           *fopen();
  184.     FILE           *fopenb();    /* open in binary mode, where needed */
  185.     char           *s;
  186.     long            nchars;
  187.     int             lines;
  188.     LPtr           *p;
  189.  
  190.     sprintf(IObuff, "\"%s\"", fname);
  191.     msg(IObuff);
  192.  
  193.     /*
  194.      * Form the backup file name - change foo.* to foo.bak - use IObuff to
  195.      * hold the backup file name 
  196.      */
  197.     strcpy(IObuff, fname);
  198.     for (s = IObuff; *s && *s != '.'; s++);
  199.     *s = NUL;
  200.     strcat(IObuff, ".bak");
  201.  
  202.     /*
  203.      * Delete any existing backup and move the current version to the backup.
  204.      * For safety, we don't remove the backup until the write has finished
  205.      * successfully. And if the 'backup' option is set, leave it around. 
  206.      */
  207.     rename(fname, IObuff);
  208.  
  209.     f = P(P_CR) ? fopen(fname, "w") : fopenb(fname, "w");
  210.     if (f == NULL) {
  211.     emsg("Can't open file for writing!");
  212.     return FALSE;
  213.     }
  214.     /*
  215.      * If we were given a bound, start there. Otherwise just start at the
  216.      * beginning of the file. 
  217.      */
  218.     if (start == NULL || start->linep == NULL)
  219.     p = Filemem;
  220.     else
  221.     p = start;
  222.  
  223.     lines = 0;
  224.     nchars = 0;
  225.     do {
  226.     fprintf(f, "%s\n", p->linep->s);
  227.     nchars += strlen(p->linep->s) + 1;
  228.     lines++;
  229.  
  230.     /*
  231.      * If we were given an upper bound, and we just did that line, then
  232.      * bag it now. 
  233.      */
  234.     if (end != NULL && end->linep != NULL) {
  235.         if (end->linep == p->linep)
  236.         break;
  237.     }
  238.     } while ((p = nextline(p)) != NULL);
  239.  
  240.     fclose(f);
  241.  
  242.     /*
  243.      * Remove the backup unless they want it left around 
  244.      */
  245.     if (!P(P_BK))
  246.     remove(IObuff);
  247.  
  248.     sprintf(IObuff, "\"%s\" %d line%s, %ld character%s", fname,
  249.         lines, (lines > 1) ? "s" : "",
  250.         nchars, (nchars > 1) ? "s" : "");
  251.     msg(IObuff);
  252.     UNCHANGED;
  253.  
  254.     return TRUE;
  255. }
  256.